// Copyright 2013 Jay Young. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview
 *
 * Provides custom errors to be thrown by RDoc code.
 */



/**
 * A base class for custom errors.
 *
 * @param {string} message The error's message text.
 * @param {boolean=} fatal Whether the error should halt processing.  Defaults to false.  Fatal
 *    errors must be re-thrown and allowed to bubble all the way up the stack and end the program.
 */
var RDocError = exports.RDocError = function(message, fatal) {
  /**
   * The error message.
   * @type {string}
   */
  this.message = message;
  
  /**
   * Whether the error should cause the program to end.
   * @type {boolean}
   */
  this.fatal = !!fatal;
};



/**
 * @return {string} The serialized error message.
 */
RDocError.prototype.toString = function() {
  return this.message;  
};



/**
 * An error message thrown when an AST node is not the right type.
 *
 * @param {Node} node The node that is not the right type.
 * @param {string} expected The expected type.
 * @param {string} actual The actual node type.
 *
 * @extends {RDocError}
 */
var NodeTypeError = exports.NodeTypeError = function(node, expected, actual) {
  /**
   * The node being inspected.
   * @type {Node}
   */
  this.node = node;
  
  /**
   * The expected node type.
   * @param {string}
   */
  this.expected = expected;
  
  /**
   * The actual node type.
   * @param {string}
   */
  this.actual = actual;
  
  var message = 'Node is not the right type.  Expected: ' + expected + ', Actual: ' + actual;
  
  RDocError.call(this, message);
};



NodeTypeError.prototype = Object.create(RDocError.prototype, {
  name: {value: 'NodeTypeError'},
  fatal: {value: true},
  constructor: {value: NodeTypeError}
});


/**
 * An error message thrown when an AST node does not have an expected property or attribute.
 *
 * @param {Node} node The node being inspected.
 * @param {string} expectedProperty The desired property which is missing from the node.
 *
 * @extends {RDocError}
 */
var NodePropError = exports.NodePropError = function(node, expectedProperty) {
  /**
   * The node being inspected.
   * @type {Node}
   */
  this.node = node;
  
  /**
   * The expected node type.
   * @param {string}
   */
  this.expectedProperty = expectedProperty;
  
  var message = 'Expected property ' + expectedProperty + ' is not present on this node.';
  
  RDocError.call(this, message);
};



NodePropError.prototype = Object.create(RDocError.prototype, {
  name: {value: 'NodePropError'},
  fata: {value: true},
  constructor: {value: NodePropError}
});
